package com.todod.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.todod.common.util.HtmlToWord;
import com.todod.common.util.TododDate;
import com.todod.entity.ResultData;
import com.todod.mapper.ConfigMenuMapper;
import com.todod.mapper.ProjectInfoMapper;
import com.todod.mapper.UsersManualFileMapper;
import com.todod.model.*;
import com.todod.service.IConfigMenuService;
import com.todod.service.IUsersManualFileService;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import org.apache.commons.compress.utils.IOUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;



/**
 * @author sxy
 * @date 2025-09-05
 */
@RestController
@RequestMapping("/configMenu")
public class ConfigMenuController {

    @Resource
    private IConfigMenuService configMenuService;

    @Resource
    private ConfigMenuMapper configMenuMapper;

    @Resource
    private IUsersManualFileService usersManualFileService;

    @Resource
    private UsersManualFileMapper usersManualFileMapper;

    @Value("${file.upload.path}")
    private String uploadPath;

    @Value("${file.upload.mapping}")
    private String showPath;

    @Value("${file.downloadDir}")
    private String downloadDir;

    @Resource
    private ProjectInfoMapper projectInfoMapper;


    /**
     *
     * @param _userId
     * @return
     */
    @RequestMapping("/getInitialLoading")
    public ResultData getInitialLoading(@RequestAttribute Long _userId, Long xmId) {
        // 获取权限数据
        List<ConfigMenu> list = configMenuService.getListByUserIdAndType(_userId, xmId);
        return ResultData.success("ok", list);
    }


    /**
     *
     * @param _userId
     * @return
     */
    @RequestMapping("/getAgainLoading")
    public ResultData getAgainLoading(@RequestAttribute Long _userId, Long xmId, Long parentId) {
        // 获取权限数据
        List<ConfigMenu> list = configMenuService.getListByUserIdAndTypeAndParentId(_userId, xmId, parentId);
        return ResultData.success("ok", list);
    }

    /**
     * @Title: getLeafNode
     * @Description: 获取全部叶子节点
     * @author dyl
     * @date: 2021-01-28
     * @return
     * @return Result
     */
    @GetMapping("/getAllLeafNode")
    public ResultData getAllLeafNode(Long xiangmuId) {

        // 获取个人创建数据
        List<ConfigMenu> list = configMenuService.getListByXmId(xiangmuId);
        ConfigMenu configMenu = new ConfigMenu();
        configMenu.setId(xiangmuId);
        configMenu.setParentId(-1L);
        configMenu.setSortNum(0);
        configMenu.setMenuName("根节点");
        configMenu.setProjectId(xiangmuId);

        list.add(configMenu);

        return ResultData.success("ok", list);
    }

    /**
     *
     * @param _userId
     * @param configMenu
     * @return
     */
    @PostMapping("/save")
    public ResultData saveData(@RequestAttribute Long _userId, @RequestBody ConfigMenu configMenu) {

        configMenuService.saveData(_userId, configMenu);
        return ResultData.success();
    }

    /**
     *
     * @param _userId
     * @param configMenu
     * @return
     */
    @PostMapping("/edit")
    public ResultData editData(@RequestAttribute Long _userId, @RequestBody ConfigMenu configMenu) {

        configMenuService.editData(_userId, configMenu);
        return ResultData.success();
    }

    /**
     *
     * @param code
     * @return
     */
    @GetMapping("/getInfo")
    public ResultData getInfo(Long code) {
        if (code == null) {
            return ResultData.error(ResultData.PARAM_ERROR_CODE, "参数错误");
        }
        return ResultData.success("ok", configMenuService.getInfo(code));
    }

    /**
     *
     * @param code
     * @return
     */
    @RequestMapping("/delete")
    public ResultData delete(Long code) {
        if (code == null) {
            return ResultData.error(ResultData.PARAM_ERROR_CODE, "参数错误");
        }
        configMenuMapper.deleteById(code);
        return ResultData.success();
    }

    /**
     * 生成md文件
     *
     * @Title: makeMD
     * @Description:
     * @author sxy
     * @param flag
     * @param ids
     * @return
     * @throws IOException
     */
    @RequestMapping(value = "/makeMD", method = RequestMethod.POST, produces = "application/json")
//    @GetMapping(value="/makeMD", method = RequestMethod.POST, produces = "application/json")
    @ResponseBody
    public void makeMD(HttpServletRequest request, HttpServletResponse response, String flag, String id,Integer level)
            throws IOException {

        if (id == null || StringUtils.isBlank(id)) {
//            return ResultData.error(ResultData.PARAM_ERROR_CODE, "参数错误");
        }

        // 创建存放生成的MD文件的根目录
        String rootDir = uploadPath + File.separator + "md_files";
        File rootDirFile = new File(rootDir);
        if (!rootDirFile.exists()) {
            rootDirFile.mkdirs();
        }

        // 生成日期子目录
        // 生成日期时间子目录，格式为：年-月-日_时-分-秒
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd_HH-mm-ss");
        String dateSubDir = LocalDateTime.now().format(formatter);

        String fullDirPath = rootDir + File.separator + dateSubDir;
        File dateDir = new File(fullDirPath);
        if (!dateDir.exists()) {
            dateDir.mkdirs();
        }

        //md文件列表
        List<UsersManualFile> list = new ArrayList<>();
        //如果不是根节点的话，则去查找UsersManualFile表里的parent_id的数据
        if (level != 1) {
            QueryWrapper<UsersManualFile> queryWrapper = new QueryWrapper<UsersManualFile>();
            queryWrapper.eq("parent_id", id);
            list = usersManualFileMapper.selectList(queryWrapper);


        }else {
            QueryWrapper<UsersManualFile> queryWrapper = new QueryWrapper<UsersManualFile>();
            queryWrapper.eq("umf_xm_id", id);
            list = usersManualFileMapper.selectList(queryWrapper);

            //mjs文件列表
            QueryWrapper<ConfigMenu> queryWrapper2 = new QueryWrapper<ConfigMenu>();
            queryWrapper2.eq("project_id", id);
            List<ConfigMenu> configMenuList = configMenuMapper.selectList(queryWrapper2);
            List<ConfigMenu> navMenuList = configMenuList;

            if (configMenuList == null || configMenuList.size() == 0) {
//                return ResultData.error(ResultData.PARAM_ERROR_CODE, "无数据");
            }
            //动态nav
            StringBuilder  mjsTemplateNav = new StringBuilder();
            mjsTemplateNav.append(
                    "      nav: [\n" +
                            "        {\n" +
                            "          text: '首页',\n" +
                            "          link: '/'\n" +
                            "        },\n"
            );
            //动态sidebar
            StringBuilder mjsTemplateSidebar = new StringBuilder();
            mjsTemplateSidebar.append("sidebar: {\n");


            //动态nav
            for (ConfigMenu configMenu : configMenuList) {
                // 二级节点为横向菜单
                if ("2".equals(configMenu.getLevel())) {
                    // 判断该菜单是否存在下拉子项
                    boolean hasSubItems = navMenuList.stream()
                            .anyMatch(menu -> menu.getParentId().equals(configMenu.getId()));

                    if (hasSubItems) {
                        // 如果有下拉子项，则使用 items 格式
                        mjsTemplateNav.append("        {\n");
                        mjsTemplateNav.append("          text: '").append(configMenu.getMenuName()).append("',\n");
                        mjsTemplateNav.append("          items: [\n");

                        for (ConfigMenu subMenu : navMenuList) {
                            if (subMenu.getParentId().equals(configMenu.getId())) {
                                mjsTemplateNav.append("            {\n");
                                mjsTemplateNav.append("              text: '").append(subMenu.getMenuName()).append("',\n");
                                mjsTemplateNav.append("              link: '").append(subMenu.getLink()).append("'\n");
                                mjsTemplateNav.append("            },\n");
                            }
                        }

                        mjsTemplateNav.append("          ]\n");
                        mjsTemplateNav.append("        },\n");
                    } else {
                        // 如果没有下拉子项，则使用简单格式
                        mjsTemplateNav.append("        {\n");
                        mjsTemplateNav.append("          text: '").append(configMenu.getMenuName()).append("',\n");
                        mjsTemplateNav.append("          link: '").append(configMenu.getLink()).append("'\n");
                        mjsTemplateNav.append("        },\n");
                    }
                }
            }


            //动态生成sidebar
            // 创建一个映射，用于存储每个路径对应的菜单项
            Map<String, List<ConfigMenu>> pathToMenus = new HashMap<>();

            for (ConfigMenu configMenu : configMenuList) {
                if ("3".equals(configMenu.getLevel()) || "4".equals(configMenu.getLevel())) {
                    // 如果是三级或四级菜单，检查其是否有对应的文档文件
                    for (UsersManualFile usersManualFile : list) {
                        if (usersManualFile.getParentId().equals(configMenu.getId())) {
                            // 根据菜单的路径分组
                            String path = configMenu.getLink();
                            pathToMenus.computeIfAbsent(path, k -> new ArrayList<>()).add(configMenu);
                        }
                    }
                }
            }

            // 生成每个路径的配置
            for (Map.Entry<String, List<ConfigMenu>> entry : pathToMenus.entrySet()) {
                String path = entry.getKey();
                List<ConfigMenu> menus = entry.getValue();

                // 对菜单项进行去重
                List<ConfigMenu> uniqueMenus = new ArrayList<>();
                for (ConfigMenu menu : menus) {
                    if (!uniqueMenus.contains(menu)) {
                        uniqueMenus.add(menu);
                    }
                }
                menus = uniqueMenus;

                mjsTemplateSidebar.append("      '").append(path).append("': {\n");
                mjsTemplateSidebar.append("        items: [\n");

                for (ConfigMenu configMenu : menus) {
                    if ("3".equals(configMenu.getLevel())) {
                        // 如果是三级菜单，直接添加文档项
                        for (UsersManualFile usersManualFile : list) {
                            if (usersManualFile.getParentId().equals(configMenu.getId())) {
                                mjsTemplateSidebar.append("          {\n");
                                mjsTemplateSidebar.append("            text: '").append(usersManualFile.getTableName()).append("',\n");
                                mjsTemplateSidebar.append("            link: '").append(usersManualFile.getLink()).append("'\n");
                                mjsTemplateSidebar.append("          },\n");
                            }
                        }
                    } else if ("4".equals(configMenu.getLevel())) {
                        // 如果是四级菜单，创建一个可折叠的项
                        mjsTemplateSidebar.append("          {\n");
                        mjsTemplateSidebar.append("            text: '").append(configMenu.getMenuName()).append("',\n");
                        mjsTemplateSidebar.append("            collapsible: true,\n");
                        mjsTemplateSidebar.append("            collapsed: false,\n");
                        mjsTemplateSidebar.append("            items: [\n");

                        // 查找对应的文档文件
                        boolean hasItems = false;
                        for (UsersManualFile usersManualFile : list) {
                            if (usersManualFile.getParentId().equals(configMenu.getId())) {
                                if (!hasItems) {
                                    hasItems = true;
                                }
                                mjsTemplateSidebar.append("              {\n");
                                mjsTemplateSidebar.append("                text: '").append(usersManualFile.getTableName()).append("',\n");
                                mjsTemplateSidebar.append("                link: '").append(usersManualFile.getLink()).append("'\n");
                                mjsTemplateSidebar.append("              },\n");
                            }
                        }

                        if (hasItems) {
                            mjsTemplateSidebar.setLength(mjsTemplateSidebar.length() - 2); // 去掉最后一个逗号
                            mjsTemplateSidebar.append("\n            ]\n");
                        } else {
                            mjsTemplateSidebar.append("            ]\n");
                        }

                        mjsTemplateSidebar.append("          },\n");
                    }
                }

                mjsTemplateSidebar.setLength(mjsTemplateSidebar.length() - 2); // 去掉最后一个逗号
                mjsTemplateSidebar.append("\n        ]\n");
                mjsTemplateSidebar.append("      },\n");
            }

            mjsTemplateSidebar.append("    },\n");


            mjsTemplateNav.append("      ]\n" +
                    "    ,\n");


            //根据id获取项目名称
            ProjectInfo projectInfo = projectInfoMapper.selectById(id);
            String  projectName = "";
            if (projectInfo != null){
                projectName = projectInfo.getXiangmumingcheng();
            }

            //配置mjs文件内容
            // 固定模板头部
            String mjsTemplateHeder = "import {defineConfig} from 'vitepress'\n" +
                    "import hljs from 'highlight.js/lib/core'\n" +
                    "import javascript from 'highlight.js/lib/languages/javascript'\n" +
                    "import xml from 'highlight.js/lib/languages/xml'\n" +
                    "import {ref} from \"./cache/deps/vue.js\";\n" +
                    "// 注册语言\n" +
                    "hljs.registerLanguage('javascript', javascript)\n" +
                    "hljs.registerLanguage('html', xml)\n" +
                    "\n" +
                    "export default defineConfig(async () => {\n" +
                    "  return {\n" +
                    "    markdown: {\n" +
                    "      theme: 'material-theme-palenight',\n" +
                    "      lineNumbers: true,\n" +
                    "      math: true,\n" +
                    "      container: {\n" +
                    "        tipLabel: '提示',\n" +
                    "        warningLabel: '警告',\n" +
                    "        dangerLabel: '危险',\n" +
                    "        infoLabel: \"信息\",\n" +
                    "        detailsLabel: \"详情\"\n" +
                    "      },\n" +
                    "\n" +
                    "    },\n" +
                    "    enhanceApp: {\n" +
                    "      setup: (ctx) => {\n" +
                    "        ctx.app.component('AdBanner', AdBanner)\n" +
                    "      }\n" +
                    "    },\n" +
                    "\n" +
                    //动态修改项目名称
                    "    title: \""+projectName+"帮助文档\",\n" +
                    "    description: \"系统使用说明\",\n" +
                    "    themeConfig: {\n" +
                    "      outline: {\n" +
                    "        level: [2, 3],\n" +
                    "        label: '页面导航'\n" +
                    "      },\n" +
                    "      siteTitle: \"帮助文档\",\n" +
                    "      logo: \"../pubilc/assets/logo.png\",\n";


            //固定模板尾部
            String mjsTemplateTail =
                    "      footer: {\n" +
                            "        message: \""+projectName+"帮助文档\",\n" +
                            "        copyright: '2025.5.20   @langtao'\n" +
                            "      },\n" +
                            "      styl: {\n" +
                            "\n" +
                            "      }\n" +
                            "\n" +
                            "    }\n" +
                            "  }\n" +
                            "})";





            // 写入动态生成的 .mjs 文件
            String mjsContent = mjsTemplateHeder+mjsTemplateNav+mjsTemplateSidebar+mjsTemplateTail;

            String fileName = "config" + ".mjs";
            String filePath = fullDirPath + File.separator + fileName;

            // 写入文件
            try (FileWriter writer = new FileWriter(filePath)) {
                writer.write(mjsContent);
            }
        }




        if (list == null || list.size() == 0) {
//            return ResultData.error(ResultData.PARAM_ERROR_CODE, "无数据");
        }





        // 存储生成的md文件的相对路径
        List<String> mdFilePaths = new ArrayList<>();

        for (UsersManualFile usersManualFile : list) {
            // 使用文件ID作为文件名前缀，避免文件名重复
            String fileNamePrefix = usersManualFile.getId().toString().substring(usersManualFile.getId().toString().length() - 8);
            String fileName = fileNamePrefix + "-" + usersManualFile.getTableName() + ".md";
            String filePath = fullDirPath + File.separator + fileName;

            // 写入MD内容
            try (FileWriter writer = new FileWriter(filePath)) {
                writer.write(usersManualFile.getMarkdownData());
            }

            // 添加相对路径到结果列表
            mdFilePaths.add("md_files/" + dateSubDir  + fileName);
        }

        // 在生成MD文件和MJS文件后，将文件夹压缩成ZIP
        String zipPath = fullDirPath + ".zip";
        FileOutputStream fos = new FileOutputStream(zipPath);
        ZipOutputStream zos = new ZipOutputStream(fos);

        // 添加文件夹到ZIP
        addFolderToZip(fullDirPath, fullDirPath, zos);

        // 关闭流
        zos.close();
        fos.close();

        // 设置响应头，以便前端下载
        response.setHeader("Content-Disposition", "attachment; filename=" + dateSubDir + ".zip");
        response.setHeader("Content-Type", "application/octet-stream");

        // 将ZIP文件发送给前端
        FileInputStream fis = new FileInputStream(zipPath);
        IOUtils.copy(fis, response.getOutputStream());
        response.getOutputStream().flush();
        fis.close();

        // 删除临时文件
//        deleteDir(new File(fullDirPath));
//        new File(zipPath).delete();


//        return ResultData.success("ok", response);
    }


    /**
     * 将文件夹添加到ZIP压缩包中
     */
    private void addFolderToZip(String srcFolder, String baseFolder, ZipOutputStream zos) throws IOException {
        File folder = new File(srcFolder);
        for (File file : folder.listFiles()) {
            if (file.isFile()) {
                FileInputStream fis = new FileInputStream(file);
                String entryName = file.getAbsolutePath().substring(baseFolder.length() + 1);
                ZipEntry entry = new ZipEntry(entryName);
                zos.putNextEntry(entry);
                IOUtils.copy(fis, zos);
                zos.closeEntry();
                fis.close();
            } else if (file.isDirectory()) {
                addFolderToZip(file.getAbsolutePath(), baseFolder, zos);
            }
        }
    }

    /**
     * 删除文件夹及其内容
     */
    private void deleteDir(File dir) {
        if (dir.isDirectory()) {
            for (File child : dir.listFiles()) {
                deleteDir(child);
            }
        }
        dir.delete();
    }

    /**
     *
     * @param _userId
     * @param request
     * @param queryUsersManualFile
     * @return
     */
    @RequestMapping("/getTreeList")
    public ResultData getTreeList(@RequestAttribute Long _userId, Long xiangmuId) {

        // 获取个人创建数据
        List<ConfigMenu> list = configMenuService.getListByXmId(xiangmuId);

        JSONObject jo = new JSONObject();
        JSONArray ja = JSONArray.fromObject(jo);
        ja.remove(0);

        jo.put("id", xiangmuId);
        jo.put("name", "用户手册目录");
        jo.put("parentId", "-1");
        jo.put("xmId", xiangmuId);
        jo.put("sortNum", "0");
        jo.put("flag", "ML");
        ja.add(jo);

        if (list != null && list.size() > 0) {
            for (ConfigMenu configMenu : list) {
                jo.put("id", configMenu.getId());
                jo.put("name", configMenu.getMenuName());
                jo.put("parentId", configMenu.getParentId());
                jo.put("xmId", configMenu.getProjectId());
                jo.put("sortNum", configMenu.getSortNum());
                jo.put("flag", "ML");
                ja.add(jo);

                // 获取个人创建数据
                List<UsersManualFile> plist = usersManualFileService.getListByClassifyId(configMenu.getId());
                for (UsersManualFile usersManualFile : plist) {
                    jo.put("id", usersManualFile.getId());
                    jo.put("name", usersManualFile.getTableName());
                    jo.put("parentId", usersManualFile.getClassifyId());
                    jo.put("xmId", usersManualFile.getXmId());
                    jo.put("sortNum", usersManualFile.getSortNum());
                    jo.put("flag", "WD");
                    jo.put("code", usersManualFile.getCode());
                    ja.add(jo);
                }
            }
        }

        return ResultData.success("ok", ja);
    }

//            //生成动态sidebar
//            for (ConfigMenu configMenu : configMenuList) {
//                //要检测的MD文件存在于3级标题或者四级标题下
//                if ("3".equals(configMenu.getLevel())){
//                    //如果存在于三级标题下的文档则需要去usersManualFile里找到parentId与configMenu.getId()相等的MD文件更新sidebar
//                    for (UsersManualFile usersManualFile : list) {
//
//                    }
//
//                }else if("4".equals(configMenu.getLevel())){
//                    //如果在四级标题下的MD文件则代表为下拉款的MD文件即一个标题下面存在多个MD文件，主标题为四级标题ConfigMenu的name，
//                    // 也是通过在usersManualFile里找到parentId与configMenu.getId()相等的MD文件更新sidebar但是格式有所不同，这样需要用到items
//
//                }
//            }




}
